﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

namespace MarlinAssistant
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
#if DEBUG
            marlinPath = System.AppDomain.CurrentDomain.BaseDirectory + @"\..\..\..\..\Marlin-bugfix-2.0.x\Marlin";
#endif
        }
        string marlinPath;// = @"D:\Documents\Desktop\MarlinAssistant\Marlin-bugfix-2.0.x\Marlin";
        const string boardPath = "\\src\\core\\boards.h";
        string configuration_h;
        string board_h;
        Dictionary<string, List<string>> dic主板型号 = new Dictionary<string, List<string>>();
        Dictionary<string, List<string>> dic屏幕控制器 = new Dictionary<string, List<string>>();
        string configuration_adv_h;

        private void button_selectMarlin_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult result = openFileDialog1.ShowDialog();
                if (result == DialogResult.OK)
                {
                    textBox_marlinPath.Text = openFileDialog1.FileName;
                    marlinPath = openFileDialog1.FileName.Substring(0, openFileDialog1.FileName.LastIndexOf('\\'));//不包含“\”
                    //System.Diagnostics.Debug.WriteLine(marlinPath);
                    初始化();
                }
            }
            catch (Exception ex)
            {
                ;
            }
        }

        void 初始化()
        {
            try
            {
                configuration_h = File.ReadAllText(marlinPath + "\\Configuration.h", Encoding.UTF8);
                configuration_adv_h = File.ReadAllText(marlinPath + "\\Configuration_adv.h", Encoding.UTF8);
                取主板型号();

                取configuration_h各设置项的默认值();
                取configuration_adv_h各设置项的默认值();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //从\src\core\boards.h读取所有的分类及各分类下的主板型号以供选择
        void 取主板型号()
        {
            try
            {
                board_h = File.ReadAllText(marlinPath + boardPath, Encoding.UTF8) + "\n//\n";   //尾巴添加“\n//\n”以方便统一正则取各型号
                comboBox_主板型号_分类.Items.Clear();
                comboBox_主板型号_分类.Tag = null;
                comboBox_主板型号.Items.Clear();
                comboBox_主板型号.Tag = null;
                dic主板型号.Clear();
                string pattern2 = @"//[ \t]+(\S.+)\n//\n([\s\S]+?)\n//\n";
                MatchCollection mc = Regex.Matches(board_h, pattern2);
                foreach (Match match in mc)
                {
                    comboBox_主板型号_分类.Items.Add(match.Groups[1].Value);
                    dic主板型号.Add(match.Groups[1].Value, 取主板型号列表(match.Groups[2].Value));
                }
            }
            catch (Exception ex)
            {
                ;
            }
        }

        //从\src\core\boards.h根据各分类读取所有的主板型号以供选择
        List<string> 取主板型号列表(string 主板型号类别)
        {
            List<string> list主板型号 = new List<string>();
            string pattern = @"#define\s+(\S+)\s+";
            foreach (Match match in Regex.Matches(主板型号类别, pattern))
            {
                list主板型号.Add(match.Groups[1].Value);
            }
            return list主板型号;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.linkLabel1.Links.Add(0, linkLabel1.Text.Length, @"https://gitee.com/wooddoor/marlin-assistant/");
#if DEBUG
            初始化();
#endif
            添加提示();
        }
        
        void 添加提示()
        {
            toolTip1.SetToolTip(checkBox_开启EEPROM, "开启后某些设置可以保存在EEPROM中重启不会丢失，\n副作用是重刷固件后，\n这些可被保存的设置并不会随固件内的修改而改变。\n启用自动调平也需要开启这个。");
            toolTip1.SetToolTip(checkBox_开启SD卡, "开启板载SD卡支持，以实现离线打印");
            toolTip1.SetToolTip(comboBox_屏幕控制器分类, "除LCD后面还有OLED、Extensible UI Displays、Graphical TFTs、Other Controllers\n目前仅仅提供LCD选项，其它屏幕请自行设置");
            toolTip1.SetToolTip(checkBox_自动调平传感器引脚AUX4, "默认接到Z轴最小值限位接口不用开启这个设置，\n如果不接Z轴最小限位，\n对于RAMPS 1.3/1.4 可以用Aux4->D32 pin，\n那就开启这个设置");
            toolTip1.SetToolTip(checkBox_BLTOUCH, "开启传感器BL TOUCH（3D TOUCH），\n其它传感器类型请自行手动到Configuration.h中开启");
            toolTip1.SetToolTip(comboBox_调平方式, "建议mega2560就用AUTO_BED_LEVELING_LINEAR，\n更好的控制器可以选AUTO_BED_LEVELING_BILINEAR");
            toolTip1.SetToolTip(textBox_探测点数, "200的热床设置为4*4点，更大的热床适当增大点数。\n这里设置一个值代表x、y方向的探测点数都为这个值，\n如果要xy方向的探测点数不同请自行修改GRID_MAX_POINTS_X、GRID_MAX_POINTS_Y为不同的值。");
            toolTip1.SetToolTip(textBox_归零时的最小高度, "不能太小，否则归零时，探针容易被热床挡住");
            toolTip1.SetToolTip(checkBox_Z_SAFE_HOMING, "设置归零时喷嘴位置，防止探针超出热床范围\n默认归零时回到热床中间，\n具体位置可以在Z_SAFE_HOMING的下两个设置项中修改");
            toolTip1.SetToolTip(checkBox_MIN_SOFTWARE_ENDSTOP_Z, "关闭后可以在屏幕菜单中手动设置Z最小为负值");
            toolTip1.SetToolTip(checkBox_Z_MIN_PROBE_ENDSTOP_INVERTING, "传感器为FIX_MOUNTED_PROBE时必须设置为true，否则编译报错。\n但是传感器设置为BLTOUCH后编译时又提示BLTOUCH必须将\nZ_MIN_PROBE_ENDSTOP_INVERTING、Z_MIN_ENDSTOP_INVERTING都设置为false");
            toolTip1.SetToolTip(checkBox_Z_MIN_ENDSTOP_INVERTING, "传感器设置为BLTOUCH后编译时提示BLTOUCH必须将\nZ_MIN_PROBE_ENDSTOP_INVERTING、Z_MIN_ENDSTOP_INVERTING都设置为false");
        }

        private void comboBox_主板型号_分类_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(comboBox_主板型号_分类.SelectedIndex >= 0)
            {
                comboBox_主板型号.Items.Clear();
                foreach(string item in dic主板型号[comboBox_主板型号_分类.SelectedItem.ToString()])
                {
                    comboBox_主板型号.Items.Add(item);
                }
            }
        }

        void 取configuration_h各设置项的默认值()
        {
            try
            {
                string pattern = @"#define\s+CONFIGURATION_H_VERSION\s+(\S+)[\r\n]";//#define CONFIGURATION_H_VERSION 02010000   #define CONFIGURATION_H_VERSION 02000902
                label_marlin版本号.Text = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+BAUDRATE\s+(\S+)\n";//#define BAUDRATE 250000
                string BAUDRATE = Regex.Match(configuration_h, pattern).Groups[1].Value;
                comboBox_波特率.SelectedItem = BAUDRATE;
                comboBox_波特率.Tag = BAUDRATE;//保存默认值，以备恢复设置时用。

                //#define LCD_LANGUAGE en
                pattern = @"#define\s+LCD_LANGUAGE\s+(\S+)\n";
                comboBox_屏幕显示语言.Tag = comboBox_屏幕显示语言.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                // //#define SDSUPPORT
                pattern = @"\n(/*)#define[ \t]+SDSUPPORT[ \t]*\n";
                checkBox_开启SD卡.Tag = checkBox_开启SD卡.Checked = (Regex.Match(configuration_h, pattern).Groups[1].Value != "//");

                //#define EXTRUDERS 1
                //#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75

                // //#define EEPROM_SETTINGS     // Persistent storage with M500 and M501
                pattern = @"\n(/*)#define[ \t]+EEPROM_SETTINGS.*\n";
                checkBox_开启EEPROM.Tag = checkBox_开启EEPROM.Checked = (Regex.Match(configuration_h, pattern).Groups[1].Value != "//");
                //   //#define EEPROM_AUTO_INIT  // Init EEPROM automatically on any errors.
                pattern = @"\n[ \t]*(/*)#define[ \t]+EEPROM_AUTO_INIT.*\n";
                checkBox_EEPROM_AUTO_INIT.Tag = checkBox_EEPROM_AUTO_INIT.Checked = (Regex.Match(configuration_h, pattern).Groups[1].Value != "//");
                //   //#define EEPROM_INIT_NOW   // Init EEPROM on first boot after a new build.
                pattern = @"\n[ \t]*(/*)#define[ \t]+EEPROM_INIT_NOW.*\n";
                checkBox_EEPROM_INIT_NOW.Tag = checkBox_EEPROM_INIT_NOW.Checked = (Regex.Match(configuration_h, pattern).Groups[1].Value != "//");

                读取主板默认型号();

                读取电机驱动默认型号();

                读取电机脉冲值();

                读取电机方向();

                读取打印平台尺寸();

                读取蜂鸣器设置();

                //读取LCD屏幕控制器类型，LCD后面还有啥OLED、Extensible UI Displays、Graphical TFTs、Other Controllers，这些慢慢看吧
                读取LCD屏幕控制器();

                读取自动调平相关设置();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取默认值出错了！");
            }
        }

        void 读取主板默认型号()
        {
            try
            {
                string pattern = @"#define\s+MOTHERBOARD\s+(\S+)\n";//#define MOTHERBOARD BOARD_RAMPS_14_EFB
                string 主板默认值 = Regex.Match(configuration_h, pattern).Groups[1].Value;
                comboBox_主板型号.Tag = 主板默认值; //将读取的文件中的MOTHERBOARD的当前值储存在comboBox_主板型号.Tag中
                //查找主板默认值分属哪一类，将相应的两个comboBox选中相应的值。
                comboBox_主板型号_分类.Tag = null;
                foreach (string key in dic主板型号.Keys)
                {
                    //System.Diagnostics.Debug.WriteLine("主板分类："+ key);
                    if (dic主板型号[key].Exists(t => t == 主板默认值))
                    {
                        comboBox_主板型号_分类.SelectedItem = key;
                        comboBox_主板型号_分类.Tag = key;
                        //comboBox_主板型号_分类_SelectedIndexChanged(comboBox_主板型号_分类, EventArgs.Empty);
                        comboBox_主板型号.SelectedItem = 主板默认值;
                        System.Diagnostics.Debug.WriteLine("找到主板默认值");
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取主板型号出错了！");
            }
        }

        void 读取电机驱动默认型号()
        {
            try
            {
                /* #define X_DRIVER_TYPE  A4988
                   #define Y_DRIVER_TYPE  A4988
                   #define Z_DRIVER_TYPE  A4988
                   #define E0_DRIVER_TYPE A4988
                 * */
                string pattern = @"#define\s+X_DRIVER_TYPE\s+(\S+)\n";
                comboBox_电机驱动型号X.Tag = comboBox_电机驱动型号X.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+Y_DRIVER_TYPE\s+(\S+)\n";
                comboBox_电机驱动型号Y.Tag = comboBox_电机驱动型号Y.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+Z_DRIVER_TYPE\s+(\S+)\n";
                comboBox_电机驱动型号Z.Tag = comboBox_电机驱动型号Z.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+E0_DRIVER_TYPE\s+(\S+)\n";
                comboBox_电机驱动型号E0.Tag = comboBox_电机驱动型号E0.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取电机驱动型号出错了！");
            }
        }

        void 读取电机脉冲值()
        {
            try
            {
                //#define DEFAULT_AXIS_STEPS_PER_UNIT   { 80, 80, 400, 500 }
                string pattern = @"#define[ \t]+DEFAULT_AXIS_STEPS_PER_UNIT[ \t]+\{[ \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[ \t]+\}[ \t]*\n";
                MatchCollection mc = Regex.Matches(configuration_h, pattern);
                textBox_X步进.Tag = textBox_X步进.Text = mc[0].Groups[1].Value;
                textBox_Y步进.Tag = textBox_Y步进.Text = mc[0].Groups[3].Value;
                textBox_Z步进.Tag = textBox_Z步进.Text = mc[0].Groups[5].Value;
                textBox_E0步进.Tag = textBox_E0步进.Text = mc[0].Groups[7].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取电机脉冲值出错了！");
            }
        }

        void 读取电机方向()
        {
            try
            {
                //#define INVERT_X_DIR false 
                //#define INVERT_Y_DIR true 
                //#define INVERT_Z_DIR false 
                //#define INVERT_E0_DIR false
                string pattern = @"#define\s+INVERT_X_DIR\s+(\S+)\n";
                comboBox_X电机运动方向.Tag = comboBox_X电机运动方向.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+INVERT_Y_DIR\s+(\S+)\n";
                comboBox_Y电机运动方向.Tag = comboBox_Y电机运动方向.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+INVERT_Z_DIR\s+(\S+)\n";
                comboBox_Z电机运动方向.Tag = comboBox_Z电机运动方向.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+INVERT_E0_DIR\s+(\S+)\n";
                comboBox_E0电机运动方向.Tag = comboBox_E0电机运动方向.SelectedItem = Regex.Match(configuration_h, pattern).Groups[1].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取电机方向出错了！");
            }
        }

        void 读取打印平台尺寸()
        {
            try
            {
                //#define X_BED_SIZE 200 
                //#define Y_BED_SIZE 200
                //#define Z_MAX_POS 170
                string pattern = @"#define\s+X_BED_SIZE\s+(\S+)\n";
                textBox_打印尺寸X.Tag = textBox_打印尺寸X.Text = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+Y_BED_SIZE\s+(\S+)\n";
                textBox_打印尺寸Y.Tag = textBox_打印尺寸Y.Text = Regex.Match(configuration_h, pattern).Groups[1].Value;

                pattern = @"#define\s+Z_MAX_POS\s+(\S+)\n";
                textBox_打印尺寸Z.Tag = textBox_打印尺寸Z.Text = Regex.Match(configuration_h, pattern).Groups[1].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取打印平台尺寸出错了！");
            }
        }

        void 读取蜂鸣器设置()
        {
            try
            {
                //#define SPEAKER
                string pattern = @"\n(/*)#define[ \t]+SPEAKER[ \t]*\n";
                checkBox_开启蜂鸣器.Tag = checkBox_开启蜂鸣器.Checked = (Regex.Match(configuration_h, pattern).Groups[1].Value != "//");
                //textBox_声音持续时间.Enabled = textBox_声音频率.Enabled = checkBox_开启蜂鸣器.Checked;
                //#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
                //#define LCD_FEEDBACK_FREQUENCY_HZ 5000
                pattern = @"\n(/*)#define[ \t]+LCD_FEEDBACK_FREQUENCY_DURATION_MS[ \t]*(\d+)[ \t]*\n";
                Match match = Regex.Match(configuration_h, pattern);
                checkBox_声音持续时间.Checked = textBox_声音持续时间.Enabled = (match.Groups[1].Value != "//");
                textBox_声音持续时间.Tag = textBox_声音持续时间.Text = match.Groups[2].Value;
                pattern = @"\n(/*)#define[ \t]+LCD_FEEDBACK_FREQUENCY_HZ[ \t]*(\d+)[ \t]*\n";
                match = Regex.Match(configuration_h, pattern);
                checkBox_声音频率.Checked = textBox_声音频率.Enabled = (match.Groups[1].Value != "//");
                textBox_声音频率.Tag = textBox_声音频率.Text = match.Groups[2].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取蜂鸣器设置出错了！");
            }
        }

        //目前仅做LCD部分，后面的OLED/TFT等等啥的，慢慢看吧
        void 读取LCD屏幕控制器()
        {
            try
            {
                //string pattern = @"//=+[ \t]+LCD / Controller Selection.+\n//=+[ \t]+(\(.+\))";//读取LCD屏幕控制器类型，LCD后面还有一类OLED、Extensible UI Displays、Graphical TFTs、Other Controllers
                string pattern = @"//=+[ \t]+LCD / Controller Selection.+\n//=+[ \t]+(\(.+\)).*\n//=+\n([\s\S]+?)\n//=+?";
                MatchCollection mc = Regex.Matches(configuration_h, pattern, RegexOptions.Multiline);
                System.Diagnostics.Debug.WriteLine("LCD分类数量："+mc.Count);
                dic屏幕控制器.Clear();
                comboBox_屏幕控制器.Tag = null;
                comboBox_屏幕控制器.Items.Clear();
                comboBox_屏幕控制器分类.Tag = null;
                comboBox_屏幕控制器分类.Items.Clear();
                foreach(Match m in mc)
                {
                    List<string> LCD_list = new List<string>();

                    pattern = @"\n(/*)#define[ \t]+(.+?)\n";// //#define REPRAP_DISCOUNT_SMART_CONTROLLER
                    MatchCollection mc2 = Regex.Matches(m.Groups[2].Value, pattern);
                    System.Diagnostics.Debug.WriteLine(m.Groups[1].Value + "分类下有几种控制器：" + mc.Count);
                    foreach (Match m2 in mc2)
                    {
                        LCD_list.Add(m2.Groups[2].Value);
                        comboBox_屏幕控制器.Items.Add(m2.Groups[2].Value);
                        if (m2.Groups[1].Value == "")
                        {
                            comboBox_屏幕控制器.Tag = m2.Groups[2].Value;
                            comboBox_屏幕控制器分类.Tag = m.Groups[1].Value;
                        }
                    }
                    dic屏幕控制器.Add("LCD" + m.Groups[1].Value, LCD_list);
                    comboBox_屏幕控制器分类.Items.Add("LCD" + m.Groups[1].Value);
                }
                if(comboBox_屏幕控制器分类.Tag != null)
                {
                    comboBox_屏幕控制器分类.SelectedItem = "LCD" + comboBox_屏幕控制器分类.Tag.ToString();
                }
                if (comboBox_屏幕控制器.Tag != null)
                {
                    comboBox_屏幕控制器.SelectedItem = comboBox_屏幕控制器.Tag.ToString();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "读取LCD屏幕控制器出现错误");
            }
        }

        void 读取自动调平相关设置()
        {
            try
            {
                string pattern = @"\n(/*)#define[ \t]+Z_MIN_PROBE_PIN.*?\n";// //#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default
                Match match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_自动调平传感器引脚AUX4.Checked = (match.Groups[1].Value=="") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+BLTOUCH.*?\n";// //#define BLTOUCH
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_BLTOUCH.Checked = (match.Groups[1].Value=="") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+Z_MIN_PROBE_REPEATABILITY_TEST.*?\n";// //#define Z_MIN_PROBE_REPEATABILITY_TEST
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_启用M48重复性测试.Checked = (match.Groups[1].Value=="") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+LCD_BED_LEVELING.*?\n";// //#define LCD_BED_LEVELING
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_启用LCD调平菜单.Checked = (match.Groups[1].Value=="") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+Z_SAFE_HOMING.*?\n";// //#define Z_SAFE_HOMING
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_Z_SAFE_HOMING.Checked = (match.Groups[1].Value=="") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+Z_MIN_PROBE_ENDSTOP_INVERTING[ \t]+\b(\w+)\b.*?\n";// #define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_Z_MIN_PROBE_ENDSTOP_INVERTING.Checked = (match.Groups[2].Value=="true") ? true : false;
                }

                pattern = @"\n(/*)[ \t]+#define[ \t]+MIN_SOFTWARE_ENDSTOP_Z.*?\n";//   #define MIN_SOFTWARE_ENDSTOP_Z
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_MIN_SOFTWARE_ENDSTOP_Z.Checked = (match.Groups[1].Value == "") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+Z_MIN_ENDSTOP_INVERTING[ \t]+\b(\w+)\b.*?\n";// #define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    checkBox_Z_MIN_ENDSTOP_INVERTING.Checked = (match.Groups[2].Value == "true") ? true : false;
                }

                pattern = @"\n(/*)#define[ \t]+NOZZLE_TO_PROBE_OFFSET[ \t]+\{[ \t]*(.*),[ \t]*(.*),[ \t]*(.*)[ \t]*\}.*?\n";// #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
                match = Regex.Match(configuration_h, pattern);
                if(match.Success)
                {
                    textBox_探针偏移X.Text = match.Groups[2].Value;
                    textBox_探针偏移Y.Text = match.Groups[3].Value;
                    textBox_探针偏移Z.Text = match.Groups[4].Value;
                }

                pattern = @"\n(/*)#define[ \t]+PROBING_MARGIN[ \t]+\b(\w+)\b.*?\n";// #define PROBING_MARGIN 10
                match = Regex.Match(configuration_h, pattern);
                if (match.Success)
                {
                    textBox_探针距离边缘的距离.Text = match.Groups[2].Value;
                }

                pattern = @"\n(/*)#define[ \t]+MULTIPLE_PROBING[ \t]+\b(\w+)\b.*?\n";// //#define MULTIPLE_PROBING 2
                match = Regex.Match(configuration_h, pattern);
                if (match.Success)
                {
                    textBox_探测次数.Enabled = checkBox_探测次数.Checked = (match.Groups[1].Value=="") ? true : false;
                    textBox_探测次数.Text = match.Groups[2].Value;
                }

                pattern = @"\n(/*)[ \t]*#define[ \t]+GRID_MAX_POINTS_X[ \t]+\b(\w+)\b.*?\n";//   #define GRID_MAX_POINTS_X 3
                match = Regex.Match(configuration_h, pattern);
                if (match.Success)
                {
                    textBox_探测点数.Text = match.Groups[2].Value;
                }

                pattern = @"\n(/*)[ \t]*#define[ \t]+Z_HOMING_HEIGHT[ \t]+\b(\w+)\b.*?\n";// //#define Z_HOMING_HEIGHT  4      // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
                match = Regex.Match(configuration_h, pattern);
                if (match.Success)
                {
                    textBox_归零时的最小高度.Enabled = checkBox_归零时的最小高度.Checked = (match.Groups[1].Value == "") ? true : false;
                    textBox_归零时的最小高度.Text = match.Groups[2].Value;
                }

                /*
                //#define AUTO_BED_LEVELING_3POINT
                //#define AUTO_BED_LEVELING_LINEAR
                //#define AUTO_BED_LEVELING_BILINEAR
                //#define AUTO_BED_LEVELING_UBL
                //#define MESH_BED_LEVELING
                */
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_3POINT).*?\n";
                match = Regex.Match(configuration_h, pattern);
                if (match.Success && (match.Groups[1].Value == "") )
                {
                    comboBox_调平方式.SelectedItem = match.Groups[2].Value;
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_LINEAR).*?\n";
                match = Regex.Match(configuration_h, pattern);
                if (match.Success && (match.Groups[1].Value == ""))
                {
                    comboBox_调平方式.SelectedItem = match.Groups[2].Value;
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_BILINEAR).*?\n";
                match = Regex.Match(configuration_h, pattern);
                if (match.Success && (match.Groups[1].Value == ""))
                {
                    comboBox_调平方式.SelectedItem = match.Groups[2].Value;
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_UBL).*?\n";
                match = Regex.Match(configuration_h, pattern);
                if (match.Success && (match.Groups[1].Value == ""))
                {
                    comboBox_调平方式.SelectedItem = match.Groups[2].Value;
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(MESH_BED_LEVELING).*?\n";
                match = Regex.Match(configuration_h, pattern);
                if (match.Success && (match.Groups[1].Value == ""))
                {
                    comboBox_调平方式.SelectedItem = match.Groups[2].Value;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取自动调平相关设置时出现错误");
            }
        }

        void 取configuration_adv_h各设置项的默认值()
        {
            try
            {
                /*
                   #if AXIS_IS_TMC(X)
                     #define X_CURRENT       800        // (mA) RMS current. Multiply by 1.414 for peak current.
                     #define X_CURRENT_HOME  X_CURRENT  // (mA) RMS current for sensorless homing
                     #define X_MICROSTEPS     16        // 0..256
                     #define X_RSENSE          0.11
                     #define X_CHAIN_POS      -1        // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
                     //#define X_INTERPOLATE  true      // Enable to override 'INTERPOLATE' for the X axis
                     //#define X_HOLD_MULTIPLIER 0.5    // Enable to override 'HOLD_MULTIPLIER' for the X axis
                   #endif
                */
                string pattern = @"\s*#if\s*AXIS_IS_TMC\(X\)[\s\S]*?#define\sX_CURRENT\s*(\S+)[\s\S]*?#define\s*X_MICROSTEPS\s*(\S+)\s";
                Match match = Regex.Match(configuration_adv_h, pattern);
                if(match.Success)
                {
                    textBox_X_CURRENT.Text = match.Groups[1].Value;
                    textBox_X_MICROSTEPS.Text = match.Groups[2].Value;
                }

                pattern = @"\s*#if\s*AXIS_IS_TMC\(Y\)[\s\S]*?#define\sY_CURRENT\s*(\S+)[\s\S]*?#define\s*Y_MICROSTEPS\s*(\S+)\s";
                match = Regex.Match(configuration_adv_h, pattern);
                if (match.Success)
                {
                    textBox_Y_CURRENT.Text = match.Groups[1].Value;
                    textBox_Y_MICROSTEPS.Text = match.Groups[2].Value;
                }

                pattern = @"\s*#if\s*AXIS_IS_TMC\(Z\)[\s\S]*?#define\sZ_CURRENT\s*(\S+)[\s\S]*?#define\s*Z_MICROSTEPS\s*(\S+)\s";
                match = Regex.Match(configuration_adv_h, pattern);
                if (match.Success)
                {
                    textBox_Z_CURRENT.Text = match.Groups[1].Value;
                    textBox_Z_MICROSTEPS.Text = match.Groups[2].Value;
                }

                pattern = @"\s*#if\s*AXIS_IS_TMC\(E0\)[\s\S]*?#define\sE0_CURRENT\s*(\S+)[\s\S]*?#define\s*E0_MICROSTEPS\s*(\S+)\s";
                match = Regex.Match(configuration_adv_h, pattern);
                if (match.Success)
                {
                    textBox_E0_CURRENT.Text = match.Groups[1].Value;
                    textBox_E0_MICROSTEPS.Text = match.Groups[2].Value;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "取configuration_adv_h各设置项的默认值时出错了");
            }
        }

        private void comboBox_屏幕控制器分类_SelectedIndexChanged(object sender, EventArgs e)
        {
            comboBox_屏幕控制器.Items.Clear();
            if(comboBox_屏幕控制器分类.SelectedIndex >=0)
            {
                foreach(string item in dic屏幕控制器[comboBox_屏幕控制器分类.SelectedItem.ToString()])
                {
                    comboBox_屏幕控制器.Items.Add(item);
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string pattern = "";
                string 修改后的设置文件 = configuration_h;
                Match m;
                //#define LCD_LANGUAGE en
                pattern = @"(#define[ \t]+LCD_LANGUAGE[ \t]+)\S+(\n)";
                修改后的设置文件 = Regex.Replace(修改后的设置文件, pattern, "$1" + comboBox_屏幕显示语言.SelectedItem.ToString() + "$2");

                pattern = @"(#define[ \t]+BAUDRATE[ \t]+)\S+(\n)";//#define BAUDRATE 250000
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + comboBox_波特率.SelectedItem.ToString() + m.Groups[2]);
                //修改后的设置文件 = Regex.Replace(修改后的设置文件, pattern, "$1" + comboBox_波特率.SelectedItem.ToString() + "$2");//奇怪，上面语言设置都正常，这里就不行了，替换后变成：$1波特率值，$1居然没有被换成第1个匹配项而是就“$1”原封不动写入去了

                // //#define SDSUPPORT
                pattern = @"\n/*(#define[ \t]+SDSUPPORT[ \t]*\n)";
                修改后的设置文件 = Regex.Replace(修改后的设置文件, pattern, checkBox_开启SD卡.Checked ? "\n$1" : "\n//$1");

                //#define EXTRUDERS 1
                //#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75

                // //#define EEPROM_SETTINGS     // Persistent storage with M500 and M501
                pattern = @"\n/*(#define[ \t]+EEPROM_SETTINGS.*\n)";
                修改后的设置文件 = Regex.Replace(修改后的设置文件, pattern, checkBox_开启EEPROM.Checked ? "\n$1" : "\n//$1");
                //   //#define EEPROM_AUTO_INIT  // Init EEPROM automatically on any errors.
                pattern = @"(\n[ \t]*)(/*)(#define[ \t]+EEPROM_AUTO_INIT.*\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_EEPROM_AUTO_INIT.Checked ? (m.Groups[1].Value + m.Groups[3].Value) : (m.Groups[1].Value + "//" + m.Groups[3].Value) );
                //   //#define EEPROM_INIT_NOW   // Init EEPROM on first boot after a new build.
                pattern = @"(\n[ \t]*)(/*)(#define[ \t]+EEPROM_INIT_NOW.*\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_EEPROM_INIT_NOW.Checked ? (m.Groups[1].Value + m.Groups[3].Value) : (m.Groups[1].Value + "//" + m.Groups[3].Value));

                pattern = @"(#define[ \t]+MOTHERBOARD[ \t]+)\S+(\n)";//#define MOTHERBOARD BOARD_RAMPS_14_EFB
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1].Value + comboBox_主板型号.SelectedItem.ToString() + m.Groups[2].Value);

                //#define X_DRIVER_TYPE  A4988
                pattern = @"(#define[ \t]+X_DRIVER_TYPE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1].Value + comboBox_电机驱动型号X.SelectedItem.ToString() + m.Groups[2].Value);
                //#define Y_DRIVER_TYPE  A4988
                pattern = @"(#define[ \t]+Y_DRIVER_TYPE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1].Value + comboBox_电机驱动型号Y.SelectedItem.ToString() + m.Groups[2].Value);
                //#define Z_DRIVER_TYPE  A4988
                pattern = @"(#define[ \t]+Z_DRIVER_TYPE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1].Value + comboBox_电机驱动型号Z.SelectedItem.ToString() + m.Groups[2].Value);
                //#define E0_DRIVER_TYPE A4988
                pattern = @"(#define[ \t]+E0_DRIVER_TYPE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1].Value + comboBox_电机驱动型号E0.SelectedItem.ToString() + m.Groups[2].Value);

                //#define DEFAULT_AXIS_STEPS_PER_UNIT   { 80, 80, 400, 500 }
                pattern = @"#define[ \t]+DEFAULT_AXIS_STEPS_PER_UNIT[ \t]+\{[ \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[, \t]+(\d+([\.]\d+)?)[ \t]+\}[ \t]*\n";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "#define DEFAULT_AXIS_STEPS_PER_UNIT { " + textBox_X步进.Text + ", " + textBox_Y步进.Text + ", " + textBox_Z步进.Text + ", " + textBox_E0步进.Text + " }\n");

                //#define INVERT_X_DIR false 
                pattern = @"(#define[ \t]+INVERT_X_DIR[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + comboBox_X电机运动方向.SelectedItem.ToString() + m.Groups[2]);
                //#define INVERT_Y_DIR true 
                pattern = @"(#define[ \t]+INVERT_Y_DIR[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + comboBox_Y电机运动方向.SelectedItem.ToString() + m.Groups[2]);
                //#define INVERT_Z_DIR false 
                pattern = @"(#define[ \t]+INVERT_Z_DIR[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + comboBox_Z电机运动方向.SelectedItem.ToString() + m.Groups[2]);
                //#define INVERT_E0_DIR false
                pattern = @"(#define[ \t]+INVERT_E0_DIR[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + comboBox_E0电机运动方向.SelectedItem.ToString() + m.Groups[2]);

                //#define X_BED_SIZE 200 
                pattern = @"(#define[ \t]+X_BED_SIZE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + textBox_打印尺寸X.Text + m.Groups[2]);
                //#define Y_BED_SIZE 200
                pattern = @"(#define[ \t]+Y_BED_SIZE[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + textBox_打印尺寸Y.Text + m.Groups[2]);
                //#define Z_MAX_POS 170
                pattern = @"(#define[ \t]+Z_MAX_POS[ \t]+)\S+(\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, m.Groups[1] + textBox_打印尺寸Z.Text + m.Groups[2]);

                //#define SPEAKER
                pattern = @"\n/*(#define[ \t]+SPEAKER[ \t]*\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_开启蜂鸣器.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]) );
                //#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
                pattern = @"\n/*(#define[ \t]+LCD_FEEDBACK_FREQUENCY_DURATION_MS[ \t]*)\d+([ \t]*\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, textBox_声音持续时间.Enabled ? ("\n" + m.Groups[1] + textBox_声音持续时间.Text + m.Groups[2]) : ("\n//" + m.Groups[1] + textBox_声音持续时间.Text + m.Groups[2]) );
                //#define LCD_FEEDBACK_FREQUENCY_HZ 5000
                pattern = @"\n/*(#define[ \t]+LCD_FEEDBACK_FREQUENCY_HZ[ \t]*)\d+([ \t]*\n)";
                m = Regex.Match(修改后的设置文件, pattern);
                修改后的设置文件 = 修改后的设置文件.Replace(m.Value, textBox_声音频率.Enabled ? ("\n" + m.Groups[1] + textBox_声音频率.Text + m.Groups[2]) : ("\n//" + m.Groups[1] + textBox_声音频率.Text + m.Groups[2]));

                // //#define REPRAP_DISCOUNT_SMART_CONTROLLER
                if(comboBox_屏幕控制器.SelectedIndex >=0)
                {
                    foreach (string lcdType in dic屏幕控制器.Keys)
                    {
                        foreach (string lcd in dic屏幕控制器[lcdType])
                        {
                            pattern = @"\n(/*)#define[ \t]+" + lcd + "\\n";
                            m = Regex.Match(修改后的设置文件, pattern);
                            修改后的设置文件 = 修改后的设置文件.Replace(m.Value, (comboBox_屏幕控制器.SelectedItem.ToString() == lcd) ? ("\n#define " + lcd + "\n") : ("\n//#define " + lcd + "\n"));
                        }
                    }
                }

                修改后的设置文件 = 写入自动调平相关设置(修改后的设置文件);

                configuration_h = 修改后的设置文件;
#if DEBUG
                File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\1.h", 修改后的设置文件);
                System.Diagnostics.Debug.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
#else
                File.WriteAllText(marlinPath + "\\Configuration.h", 修改后的设置文件);
#endif
                MessageBox.Show("成功写入设置");

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "写入设置出错了！");
            }
        }

        string 写入自动调平相关设置(string 修改后的设置文件)
        {
            try
            {
                string pattern = @"\n/*(#define[ \t]+Z_MIN_PROBE_PIN.*?\n)";// //#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default
                Match m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_自动调平传感器引脚AUX4.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]));
                }

                pattern = @"\n/*(#define[ \t]+BLTOUCH.*?\n)";// //#define BLTOUCH
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_BLTOUCH.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]));
                }

                pattern = @"\n/*(#define[ \t]+Z_MIN_PROBE_REPEATABILITY_TEST.*?\n)";// //#define Z_MIN_PROBE_REPEATABILITY_TEST
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_启用M48重复性测试.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]));
                }

                pattern = @"\n/*(#define[ \t]+LCD_BED_LEVELING.*?\n)";// //#define LCD_BED_LEVELING
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_启用LCD调平菜单.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]));
                }

                pattern = @"\n/*(#define[ \t]+Z_SAFE_HOMING.*?\n)";// //#define Z_SAFE_HOMING
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_Z_SAFE_HOMING.Checked ? ("\n" + m.Groups[1]) : ("\n//" + m.Groups[1]));
                }

                pattern = @"\n(/*)(#define[ \t]+Z_MIN_PROBE_ENDSTOP_INVERTING[ \t]+)\b\w+\b(.*?\n)";// #define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_Z_MIN_PROBE_ENDSTOP_INVERTING.Checked ? ("\n" + m.Groups[2] + "true" + m.Groups[3]) : ("\n" + m.Groups[2] + "false" + m.Groups[3]) );
                }

                pattern = @"\n(/*)([ \t]+#define[ \t]+MIN_SOFTWARE_ENDSTOP_Z.*?\n)";//   #define MIN_SOFTWARE_ENDSTOP_Z
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_MIN_SOFTWARE_ENDSTOP_Z.Checked ? ("\n" + m.Groups[2]) : ("\n//" + m.Groups[2]));
                }

                pattern = @"\n(/*)(#define[ \t]+Z_MIN_ENDSTOP_INVERTING[ \t]+)\b\w+\b(.*?\n)";// #define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, checkBox_Z_MIN_ENDSTOP_INVERTING.Checked ? ("\n" + m.Groups[2] + "true" + m.Groups[3]) : ("\n" + m.Groups[2] + "false" + m.Groups[3]));
                }

                pattern = @"\n(/*)#define[ \t]+NOZZLE_TO_PROBE_OFFSET[ \t]+\{[ \t]*(.*),[ \t]*(.*),[ \t]*(.*)[ \t]*\}.*?\n";// #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n#define NOZZLE_TO_PROBE_OFFSET { " + textBox_探针偏移X.Text + ", " + textBox_探针偏移Y.Text + ", " + textBox_探针偏移Z.Text + " }\n");
                }

                pattern = @"\n(/*)#define[ \t]+PROBING_MARGIN[ \t]+\b(\w+)\b.*?\n";// #define PROBING_MARGIN 10
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n#define PROBING_MARGIN " + textBox_探针距离边缘的距离.Text + " \n");
                }

                pattern = @"\n(/*)#define[ \t]+MULTIPLE_PROBING[ \t]+\b(\w+)\b.*?\n";// //#define MULTIPLE_PROBING 2
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (textBox_探测次数.Enabled ? "" : "//") + "#define MULTIPLE_PROBING " + textBox_探测次数.Text + " \n");
                }

                pattern = @"\n(/*)[ \t]*#define[ \t]+GRID_MAX_POINTS_X[ \t]+\b(\w+)\b.*?\n";//   #define GRID_MAX_POINTS_X 3
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n  #define GRID_MAX_POINTS_X " + textBox_探测点数.Text + " \n");
                }

                pattern = @"\n(/*)[ \t]*#define[ \t]+Z_HOMING_HEIGHT[ \t]+\b(\w+)\b(.*?\n)";// //#define Z_HOMING_HEIGHT  4      // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (textBox_归零时的最小高度.Enabled ? "" : "//") + "#define Z_HOMING_HEIGHT " + textBox_归零时的最小高度.Text + m.Groups[3].Value);
                }

                /*
                //#define AUTO_BED_LEVELING_3POINT
                //#define AUTO_BED_LEVELING_LINEAR
                //#define AUTO_BED_LEVELING_BILINEAR
                //#define AUTO_BED_LEVELING_UBL
                //#define MESH_BED_LEVELING
                */
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_3POINT).*?\n";
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + ( ( (comboBox_调平方式.SelectedIndex>=0) && (comboBox_调平方式.SelectedItem.ToString() == "AUTO_BED_LEVELING_3POINT") ) ? "" : "//") + "#define AUTO_BED_LEVELING_3POINT\n");
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_LINEAR).*?\n";
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (((comboBox_调平方式.SelectedIndex >= 0) && (comboBox_调平方式.SelectedItem.ToString() == "AUTO_BED_LEVELING_LINEAR")) ? "" : "//") + "#define AUTO_BED_LEVELING_LINEAR\n");
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_BILINEAR).*?\n";
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (((comboBox_调平方式.SelectedIndex >= 0) && (comboBox_调平方式.SelectedItem.ToString() == "AUTO_BED_LEVELING_BILINEAR")) ? "" : "//") + "#define AUTO_BED_LEVELING_BILINEAR\n");
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(AUTO_BED_LEVELING_UBL).*?\n";
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (((comboBox_调平方式.SelectedIndex >= 0) && (comboBox_调平方式.SelectedItem.ToString() == "AUTO_BED_LEVELING_UBL")) ? "" : "//") + "#define AUTO_BED_LEVELING_UBL\n");
                }
                pattern = @"\n(/*)[ \t]*#define[ \t]+(MESH_BED_LEVELING).*?\n";
                m = Regex.Match(修改后的设置文件, pattern);
                if (m.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(m.Value, "\n" + (((comboBox_调平方式.SelectedIndex >= 0) && (comboBox_调平方式.SelectedItem.ToString() == "MESH_BED_LEVELING")) ? "" : "//") + "#define MESH_BED_LEVELING\n");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("写入自动调平相关设置时出现错误");
            }

            return 修改后的设置文件;
        }

        private void checkBox_探测次数_CheckedChanged(object sender, EventArgs e)
        {
            textBox_探测次数.Enabled = checkBox_探测次数.Checked;
        }

        private void checkBox_归零时的最小高度_CheckedChanged(object sender, EventArgs e)
        {
            textBox_归零时的最小高度.Enabled = checkBox_归零时的最小高度.Checked;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                /*
                   #if AXIS_IS_TMC(X)
                     #define X_CURRENT       800        // (mA) RMS current. Multiply by 1.414 for peak current.
                     #define X_CURRENT_HOME  X_CURRENT  // (mA) RMS current for sensorless homing
                     #define X_MICROSTEPS     16        // 0..256
                     #define X_RSENSE          0.11
                     #define X_CHAIN_POS      -1        // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
                     //#define X_INTERPOLATE  true      // Enable to override 'INTERPOLATE' for the X axis
                     //#define X_HOLD_MULTIPLIER 0.5    // Enable to override 'HOLD_MULTIPLIER' for the X axis
                   #endif
                */
                string 修改后的设置文件 = configuration_adv_h;
                string pattern = @"(\s*#if\s*AXIS_IS_TMC\(X\)[\s\S]*?#define\sX_CURRENT\s*)(\S+)([\s\S]*?#define\s*X_MICROSTEPS\s*)(\S+)(\s)";
                Match match = Regex.Match(修改后的设置文件, pattern);
                if (match.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(match.Value, match.Groups[1].Value + textBox_X_CURRENT.Text + match.Groups[3].Value + textBox_X_MICROSTEPS.Text + match.Groups[5].Value);
                }

                pattern = @"(\s*#if\s*AXIS_IS_TMC\(Y\)[\s\S]*?#define\sY_CURRENT\s*)(\S+)([\s\S]*?#define\s*Y_MICROSTEPS\s*)(\S+)(\s)";
                match = Regex.Match(修改后的设置文件, pattern);
                if (match.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(match.Value, match.Groups[1].Value + textBox_Y_CURRENT.Text + match.Groups[3].Value + textBox_Y_MICROSTEPS.Text + match.Groups[5].Value);
                }

                pattern = @"(\s*#if\s*AXIS_IS_TMC\(Z\)[\s\S]*?#define\sZ_CURRENT\s*)(\S+)([\s\S]*?#define\s*Z_MICROSTEPS\s*)(\S+)(\s)";
                match = Regex.Match(修改后的设置文件, pattern);
                if (match.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(match.Value, match.Groups[1].Value + textBox_Z_CURRENT.Text + match.Groups[3].Value + textBox_Z_MICROSTEPS.Text + match.Groups[5].Value);
                }

                pattern = @"(\s*#if\s*AXIS_IS_TMC\(E0\)[\s\S]*?#define\sE0_CURRENT\s*)(\S+)([\s\S]*?#define\s*E0_MICROSTEPS\s*)(\S+)(\s)";
                match = Regex.Match(修改后的设置文件, pattern);
                if (match.Success)
                {
                    修改后的设置文件 = 修改后的设置文件.Replace(match.Value, match.Groups[1].Value + textBox_E0_CURRENT.Text + match.Groups[3].Value + textBox_E0_MICROSTEPS.Text + match.Groups[5].Value);
                }

                configuration_adv_h = 修改后的设置文件;
#if DEBUG
                File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\2.h", 修改后的设置文件);
#else
                File.WriteAllText(marlinPath + "\\Configuration_adv.h", 修改后的设置文件);
#endif
                MessageBox.Show("成功写入设置");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "取configuration_adv_h各设置项的默认值时出错了");
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://gitee.com/wooddoor/marlin-assistant/");
        }

        private void checkBox_声音持续时间_CheckedChanged(object sender, EventArgs e)
        {
            textBox_声音持续时间.Enabled = checkBox_声音持续时间.Checked;
        }

        private void checkBox_声音频率_CheckedChanged(object sender, EventArgs e)
        {
            textBox_声音频率.Enabled = checkBox_声音频率.Checked;
        }
    }
}
